<template>
  <div class="tree-container" ref="treeContainer">
    <div class="tree-header">
      <span class="text-h6">树形结构</span>
      <!-- 展开/收起全部 -->
      <q-btn
        flat
        dense
        round
        :icon="isExpandedAll ? 'expand_more' : 'expand_less'"
        @click="toggleExpandAll"
        :title="isExpandedAll ? '收起全部' : '展开全部'"
      />
    </div>

    <!-- 使用提示 -->
    <div class="usage-tip">
      <q-icon name="info" size="sm" />
      <span>右键点击节点显示菜单，支持连续右键切换位置</span>
    </div>
    <TreeNode
      :node="treeData"
      :level="0"
      :expanded-set="expandedSet"
      @toggle-expanded="handleToggleExpanded"
      @drag-start="handleDragStart"
      @drag-end="handleDragEnd"
      @drag-add="handleDragAdd"
      @drag-move="handleDragMove"
      @context-menu="handleContextMenu"
    />

    <!-- 右键菜单 -->
    <ContextMenu
      :visible="contextMenuVisible"
      :position="contextMenuPosition"
      :items="contextMenuItems"
      :target-data="contextMenuTarget"
      @close="closeContextMenu"
      @item-click="handleMenuItemClick"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
import TreeNode from "./TreeNode.vue";
import ContextMenu from "./ContextMenu.vue";
import type {
  TreeNode as TreeNodeType,
  MenuItem,
  MenuPosition,
} from "../types/node";

const treeData = ref<TreeNodeType[]>([
  {
    id: 1,
    label: "容器 1",
    children: [
      {
        id: 2,
        label: "文本 1",
        children: undefined,
        // 叶子节点不需要 children 属性
      },
      {
        id: 3,
        label: "容器 2",
        children: [
          {
            id: 4,
            label: "容器 3",
            children: [
              { id: 6, label: "文本 2" },
              { id: 7, label: "文本 3" },
            ],
          },
        ],
      },
    ],
  },
  {
    id: 5,
    label: "容器 4",
    children: [
      { id: 8, label: "文本 4" },
      {
        id: 9,
        label: "容器 5",
        children: [{ id: 10, label: "文本 5" }],
      },
    ],
  },
  {
    id: 11,
    label: "容器 6",
    children: [],
  },
  {
    id: 12,
    label: "文本 6",
    children: undefined,
  },
  {
    id: 13,
    label: "容器 7",
    children: [],
  },
  {
    id: 14,
    label: "容器 8",
    children: [],
  },
  {
    id: 15,
    label: "容器 9",
    children: [],
  },
]);

const treeContainer = ref<HTMLDivElement | null>(null);

// #region 展开收起
// 收集所有有子节点的节点ID
const getAllParentNodeIds = (nodes: TreeNodeType[]): number[] => {
  const ids: number[] = [];
  const traverse = (nodeList: TreeNodeType[]) => {
    nodeList.forEach((node) => {
      if (node.children && node.children.length > 0) {
        ids.push(node.id);
        traverse(node.children);
      }
    });
  };
  traverse(nodes);
  return ids;
};

const allParentIds = getAllParentNodeIds(treeData.value);
console.log(allParentIds);

// 使用响应式 Set 来管理展开状态
const expandedSet = reactive(new Set<number>(allParentIds)); // 默认展开所有节点
console.log(expandedSet, "expandedSet");
const isExpandedAll = ref<boolean>(true);

const toggleExpandAll = () => {
  isExpandedAll.value = !isExpandedAll.value;
  console.dir(treeContainer.value?.querySelectorAll, "treeContainer.value");
  if (isExpandedAll.value) {
    // 展开全部
    allParentIds.forEach((id) => expandedSet.add(id));
  } else {
    // 收起全部
    expandedSet.clear();
  }
};

const handleToggleExpanded = (nodeId: number) => {
  if (expandedSet.has(nodeId)) {
    expandedSet.delete(nodeId);
  } else {
    expandedSet.add(nodeId);
  }
};
// #endregion

// #region 拖拽
const handleDragActive = (type: "add" | "remove") => {
  const allTreeNodes = treeContainer.value?.querySelectorAll(".tree-node");
  allTreeNodes?.forEach((node) => {
    if (type === "add") {
      node.classList.add("dragging-active");
    } else {
      node.classList.remove("dragging-active");
    }
  });
};

const handleDragStart = (e: any) => {
  console.log("拖拽开始", e);
  handleDragActive("add");
};

const handleDragEnd = (e: any) => {
  console.log("拖拽结束", e);
  handleDragActive("remove");
};

const handleDragAdd = (e: any) => {
  console.log("拖拽添加", e);
};

const handleDragMove = (e: any) => {
  // console.log("拖拽移动", e);
};
// #endregion

// #region 右键菜单
const contextMenuVisible = ref(false);
const contextMenuPosition = ref<MenuPosition>({ x: 0, y: 0 });
const contextMenuTarget = ref<TreeNodeType | null>(null);

// 定义右键菜单项
const contextMenuItems = ref<MenuItem[]>([
  {
    name: "add-child",
    title: "添加子节点",
    icon: "add",
    shortcuts: "Ctrl+N",
  },
  {
    name: "edit",
    title: "编辑节点",
    icon: "edit",
    shortcuts: "F2",
  },
  {
    name: "more",
    title: "更多操作",
    icon: "more_horiz",
    children: [
      {
        name: "expand-all",
        title: "展开所有子节点",
        icon: "unfold_more",
      },
      {
        name: "collapse-all",
        title: "收起所有子节点",
        icon: "unfold_less",
      },
      {
        name: "move-up",
        title: "上移",
        icon: "keyboard_arrow_up",
      },
      {
        name: "move-down",
        title: "下移",
        icon: "keyboard_arrow_down",
      },
    ],
  },
  {
    name: "copy",
    title: "复制节点",
    icon: "content_copy",
    shortcuts: "Ctrl+C",
  },
  {
    name: "cut",
    title: "剪切节点",
    icon: "content_cut",
    shortcuts: "Ctrl+X",
  },
  {
    name: "paste",
    title: "粘贴节点",
    icon: "content_paste",
    shortcuts: "Ctrl+V",
    disabled: true, // 示例：禁用状态
  },
  {
    name: "delete",
    title: "删除节点",
    icon: "delete",
    shortcuts: "Delete",
  },
]);

// 处理右键菜单显示
const handleContextMenu = (event: MouseEvent, node: TreeNodeType) => {
  event.preventDefault();

  // 更新鼠标位置和目标节点
  contextMenuPosition.value = { x: event.clientX, y: event.clientY };
  contextMenuTarget.value = node;

  // 无论菜单是否已显示，都设置为显示状态
  // ContextMenu组件会通过watch监听position变化并重新调整位置
  contextMenuVisible.value = true;
};

// 关闭右键菜单
const closeContextMenu = () => {
  contextMenuVisible.value = false;
  contextMenuTarget.value = null;
};

// 处理菜单项点击
const handleMenuItemClick = (menuItem: MenuItem, targetData?: TreeNodeType) => {
  const target = targetData || contextMenuTarget.value;
  if (!target) return;

  console.log("菜单项点击:", menuItem.name, "目标节点:", target);

  switch (menuItem.name) {
    case "add-child":
      console.log("添加子节点到:", target.label);
      break;
    case "edit":
      console.log("编辑节点:", target.label);
      break;
    case "copy":
      console.log("复制节点:", target.label);
      break;
    case "cut":
      console.log("剪切节点:", target.label);
      break;
    case "paste":
      console.log("粘贴到节点:", target.label);
      break;
    case "expand-all":
      console.log("展开所有子节点:", target.label);
      break;
    case "collapse-all":
      console.log("收起所有子节点:", target.label);
      break;
    case "move-up":
      console.log("上移节点:", target.label);
      break;
    case "move-down":
      console.log("下移节点:", target.label);
      break;
    case "delete":
      console.log("删除节点:", target.label);
      break;
    default:
      console.log("未处理的菜单项:", menuItem.name);
  }
};
// #endregion
</script>

<style scoped>
.tree-container {
  padding: 16px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.tree-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.tree-header .text-h6 {
  margin: 0;
  color: #333;
}

.usage-tip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background-color: #f0f8ff;
  border: 1px solid #e3f2fd;
  border-radius: 4px;
  margin-bottom: 12px;
  font-size: 14px;
  color: #1976d2;
}
</style>
